package com.example.bookstore.controllers;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.UserTransaction;

import com.example.bookstore.cart.ShoppingCart;
import com.example.bookstore.cart.ShoppingCartItem;
import com.example.bookstore.details.CustomerDetails;
import com.example.bookstore.entity.Book;
import com.example.bookstore.entity.Customer;
import com.example.bookstore.entity.Order;
import com.example.bookstore.entity.OrderItem;
import com.example.bookstore.exception.BookNotFoundException;
import com.example.bookstore.exception.BooksNotFoundException;
import com.example.bookstore.exception.OrderException;

@ManagedBean(name = "bookCtrl")
@SessionScoped
public class BookController {

	@PersistenceContext(name = "dukesbooks")
	private EntityManager em;

	@Resource
	private UserTransaction utx;

	public List<Book> getBooks() throws BooksNotFoundException {
		try {
			List<Book> results = em.createQuery("SELECT bd FROM Book bd ORDER BY bd.bookId",
					Book.class).getResultList();
			
			return results;
		} catch (Exception ex) {
			throw new BooksNotFoundException("Could not get books: "
					+ ex.getMessage());
		}
	}

	public Book getBook(String bookId) throws BookNotFoundException {
		long id = Long.parseLong(bookId);
		Book requestedBook = em.find(Book.class, id);

		if (requestedBook == null) {
			throw new BookNotFoundException("Couldn't find book: " + bookId);
		}

		return requestedBook;
	}

	public void buyBooks(ShoppingCart cart, CustomerDetails cus)
			throws OrderException {
		List<ShoppingCartItem> items = cart.getItems();

		try {
			utx.begin();
			Order order = new Order();
			order.setBillDate(new Date());
			order.setShipDate(new Date());
			order.setTotal(cart.getTotal());

			Customer customer = em.find(Customer.class, cus.getCustomerId());
			System.out.println("BookController: customer"
					+ customer.getCustomerId());
			order.setCustomer(customer);
			em.persist(order);

			for (ShoppingCartItem sci : items) {
				Book bd = sci.getItem();
				String id = bd.getBookId();
				int quantity = sci.getQuantity();
				OrderItem item = buyBook(id, quantity);
				item.setOrder(order);
				em.persist(item);
			}

			utx.commit();
		} catch (Exception ex) {
			throw new OrderException("Commit failed: " + ex.getMessage());
		}
	}

	public OrderItem buyBook(String bookId, int quantity) throws OrderException {
		OrderItem item = null;
		try {
			long id = Long.parseLong(bookId);
			Book requestedBook = em.find(Book.class, id);

			if (requestedBook != null) {
				int inventory = requestedBook.getInventory();
				System.out.println("BookController: buyBook(" + bookId + ", "
						+ quantity + ")");
				if ((inventory - quantity) >= 0) {
					int newInventory = inventory - quantity;
					requestedBook.setInventory(newInventory);

					item = new OrderItem();
					item.setBookId(id);
					item.setQuantity(quantity);
					item.setPrice(new BigDecimal(quantity
							* requestedBook.getPrice()));

				} else {
					throw new OrderException("Not enough of " + bookId
							+ " in stock to complete order.");
				}
			}
		} catch (Exception ex) {
			throw new OrderException("Couldn't purchase book: "
					+ ex.getMessage());
		}

		return item;
	}

	public void remove() {
		try {
			em.close();
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}
}
